00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "action.h"
00023
00024 #include <SDL_net.h>
00025 #include "action_handler.h"
00026 #include "../tool/debug.h"
00027 #include "../game/time.h"
00028 #include "../character/character.h"
00029 #include "../team/teams_list.h"
00030
00031
00032
00033 Action::Action (Action_t type)
00034 {
00035 var.clear();
00036 m_type = type;
00037 m_timestamp = Time::GetInstance()->Read();
00038 }
00039
00040
00041 Action::Action (Action_t type, int value) : m_type(type)
00042 {
00043 var.clear();
00044 Push(value);
00045 m_timestamp = Time::GetInstance()->Read();
00046 }
00047
00048 Action::Action (Action_t type, double value) : m_type(type)
00049 {
00050 var.clear();
00051 Push(value);
00052 m_timestamp = Time::GetInstance()->Read();
00053 }
00054
00055 Action::Action (Action_t type, const std::string& value) : m_type(type)
00056 {
00057 var.clear();
00058 Push(value);
00059 m_timestamp = Time::GetInstance()->Read();
00060 }
00061
00062 Action::Action (Action_t type, double value1, double value2) : m_type(type)
00063 {
00064 var.clear();
00065 Push(value1);
00066 Push(value2);
00067 m_timestamp = Time::GetInstance()->Read();
00068 }
00069
00070 Action::Action (Action_t type, double value1, int value2) : m_type(type)
00071 {
00072 var.clear();
00073 Push(value1);
00074 Push(value2);
00075 m_timestamp = Time::GetInstance()->Read();
00076 }
00077
00078
00079 Action::Action (const char *is)
00080 {
00081 var.clear();
00082 m_type = (Action_t)SDLNet_Read32(is);
00083 is += 4;
00084 m_timestamp = (Action_t)SDLNet_Read32(is);
00085 is += 4;
00086 int m_lenght = SDLNet_Read32(is);
00087 is += 4;
00088
00089 for(int i=0; i < m_lenght; i++)
00090 {
00091 Uint32 val = SDLNet_Read32(is);
00092 var.push_back(val);
00093 is += 4;
00094 }
00095 }
00096
00097 Action::~Action ()
00098 {
00099 }
00100
00101 Action::Action_t Action::GetType() const
00102 {
00103 return m_type;
00104 }
00105
00106 bool Action::IsEmpty() const
00107 {
00108 return var.empty();
00109 }
00110
00111 void Action::SetTimestamp(uint timestamp)
00112 {
00113 m_timestamp = timestamp;
00114 }
00115
00116 uint Action::GetTimestamp()
00117 {
00118 return m_timestamp;
00119 }
00120
00121
00122 void Action::WritePacket(char* &packet, int & size)
00123 {
00124 size = 4
00125 + 4
00126 + 4
00127 + int(var.size()) * 4;
00128
00129 packet = (char*)malloc(size);
00130 char* os = packet;
00131
00132 SDLNet_Write32(m_type, os);
00133 os += 4;
00134 SDLNet_Write32(m_timestamp, os);
00135 os += 4;
00136 Uint32 param_size = (Uint32)var.size();
00137 SDLNet_Write32(param_size, os);
00138 os += 4;
00139
00140 for(std::list<Uint32>::iterator val = var.begin(); val!=var.end(); val++)
00141 {
00142 SDLNet_Write32(*val, os);
00143 os += 4;
00144 }
00145 }
00146
00147
00148 void Action::Push(int val)
00149 {
00150 Uint32 tmp;
00151 memcpy(&tmp, &val, 4);
00152 var.push_back(tmp);
00153 MSG_DEBUG( "action", " (%s) Pushing int : %i",
00154 ActionHandler::GetInstance()->GetActionName(m_type).c_str(), val);
00155
00156 }
00157
00158 void Action::Push(double val)
00159 {
00160 Uint32 tmp[2];
00161 memcpy(&tmp, &val, 8);
00162 #if (SDL_BYTEORDER == SDL_LIL_ENDIAN)
00163 var.push_back(tmp[0]);
00164 var.push_back(tmp[1]);
00165 #else
00166 var.push_back(tmp[1]);
00167 var.push_back(tmp[0]);
00168 #endif
00169
00170 MSG_DEBUG( "action", " (%s) Pushing double : %f",
00171 ActionHandler::GetInstance()->GetActionName(m_type).c_str(), val);
00172 }
00173
00174 void Action::Push(const Point2i& val)
00175 {
00176 Push(val.x);
00177 Push(val.y);
00178 }
00179
00180 void Action::Push(const Point2d& val)
00181 {
00182 Push(val.x);
00183 Push(val.y);
00184 }
00185
00186 void Action::Push(std::string val)
00187 {
00188
00189
00190 Push((int)val.size());
00191 char* ch = (char*)val.c_str();
00192
00193 int count = val.size();
00194 while(count > 0)
00195 {
00196 Uint32 tmp = 0;
00197
00198 #if (SDL_BYTEORDER == SDL_LIL_ENDIAN)
00199 strncpy((char*)&tmp, ch, 4);
00200 var.push_back(tmp);
00201 ch += 4;
00202 count -= 4;
00203 #else
00204 char* c_tmp = (char*)&tmp;
00205 c_tmp +=3;
00206 for(int i=0; i < 4; i++)
00207 *(c_tmp--) = *(ch++);
00208
00209 var.push_back(tmp);
00210 count -= 4;
00211 #endif
00212 }
00213 MSG_DEBUG( "action", " (%s) Pushing string : %s",
00214 ActionHandler::GetInstance()->GetActionName(m_type).c_str(), val.c_str());
00215 }
00216
00217
00218 int Action::PopInt()
00219 {
00220 assert(var.size() > 0);
00221 if(var.size() <= 0)
00222 return 0;
00223 int val;
00224 Uint32 tmp = var.front();
00225 memcpy(&val, &tmp, 4);
00226 var.pop_front();
00227 MSG_DEBUG( "action", " (%s) Poping int : %i",
00228 ActionHandler::GetInstance()->GetActionName(m_type).c_str(), val);
00229 return val;
00230 }
00231
00232 double Action::PopDouble()
00233 {
00234 assert(var.size() > 0);
00235 if(var.size() <= 0)
00236 return 0.0;
00237 double val;
00238 Uint32 tmp[2];
00239 #if (SDL_BYTEORDER == SDL_LIL_ENDIAN)
00240 tmp[0] = var.front();
00241 var.pop_front();
00242 tmp[1] = var.front();
00243 var.pop_front();
00244 memcpy(&val, &tmp, 8);
00245 #else
00246 tmp[1] = var.front();
00247 var.pop_front();
00248 tmp[0] = var.front();
00249 var.pop_front();
00250 memcpy(&val, &tmp, 8);
00251 #endif
00252
00253 MSG_DEBUG( "action", " (%s) Poping double : %f",
00254 ActionHandler::GetInstance()->GetActionName(m_type).c_str(), val);
00255 return val;
00256 }
00257
00258 std::string Action::PopString()
00259 {
00260 assert(var.size() > 1);
00261 if(var.size() <= 1)
00262 return "";
00263 int lenght = PopInt();
00264
00265 std::string str="";
00266
00267 assert((int)var.size() >= lenght/4);
00268 if((int)var.size() < lenght/4)
00269 return "";
00270
00271 while(lenght > 0)
00272 {
00273 Uint32 tmp = var.front();
00274 var.pop_front();
00275 char tmp_str[5] = {0, 0, 0, 0, 0};
00276 #if (SDL_BYTEORDER == SDL_LIL_ENDIAN)
00277 memcpy(tmp_str, &tmp, 4);
00278 str += tmp_str;
00279 lenght -= 4;
00280 #else
00281 char* c_tmp_str = (char*)(&tmp_str) + 3;
00282 char* c_tmp = (char*)&tmp;
00283 for(int i=0; i < 4; i++)
00284 *(c_tmp_str--) = *(c_tmp++);
00285
00286 str += tmp_str;
00287 lenght -= 4;
00288 #endif
00289 }
00290 MSG_DEBUG( "action", " (%s) Poping string : %s",
00291 ActionHandler::GetInstance()->GetActionName(m_type).c_str(), str.c_str());
00292 return str;
00293 }
00294
00295 Point2i Action::PopPoint2i()
00296 {
00297 int x, y;
00298 x = PopInt();
00299 y = PopInt();
00300 return Point2i(x, y);
00301 }
00302
00303 Point2d Action::PopPoint2d()
00304 {
00305 double x, y;
00306 x = PopDouble();
00307 y = PopDouble();
00308 return Point2d(x, y);
00309 }
00310
00311
00312 void Action::StoreActiveCharacter()
00313 {
00314 StoreCharacter(ActiveCharacter().GetTeamIndex() ,ActiveCharacter().GetCharacterIndex());
00315 }
00316
00317 void Action::StoreCharacter(uint team_no, uint char_no)
00318 {
00319 Push((int)team_no);
00320 Push((int)char_no);
00321 Character * c = teams_list.FindPlayingByIndex(team_no)->FindByIndex(char_no);
00322 Push(c->GetPosition());
00323 Push((int)c->GetDirection());
00324 Push(c->GetAbsFiringAngle());
00325 Push(c->GetEnergy());
00326 Push((int)c->GetDiseaseDamage());
00327 Push((int)c->GetDiseaseDuration());
00328 Push(c->GetSpeed());
00329 if(c->IsActiveCharacter()) {
00330 Push((int)true);
00331 Push(ActiveTeam().ActiveCharacter().GetBody()->GetClothe());
00332 Push(ActiveTeam().ActiveCharacter().GetBody()->GetMovement());
00333 Push((int)ActiveTeam().ActiveCharacter().GetBody()->GetFrame());
00334 } else {
00335 Push((int)false);
00336 }
00337 }
00338
00339 void Action::RetrieveCharacter()
00340 {
00341 int team_no = PopInt();
00342 int char_no = PopInt();
00343 Character * c = teams_list.FindPlayingByIndex(team_no)->FindByIndex(char_no);
00344 c->SetXY(PopPoint2i());
00345 c->SetDirection((Body::Direction_t)PopInt());
00346 c->SetFiringAngle(PopDouble());
00347 c->SetEnergy(PopInt());
00348 int disease_damage_per_turn = PopInt();
00349 int disease_duration = PopInt();
00350 c->SetDiseaseDamage(disease_damage_per_turn, disease_duration);
00351 c->SetSpeedXY(PopPoint2d());
00352 if((bool)PopInt()) {
00353 if(c->GetTeam().IsActiveTeam())
00354 ActiveTeam().SelectCharacter(char_no);
00355 c->SetClothe(PopString());
00356 c->SetMovement(PopString());
00357 c->GetBody()->SetFrame((uint)PopInt());
00358 }
00359 }
00360
00361
00362