⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cell.cpp

📁 通用网络游戏开发框架
💻 CPP
📖 第 1 页 / 共 2 页
字号:

   if (side == -1) {
      clear_vector(all_vectors);
      return;
   }

   vector[side] = ! vector[side];
   changed      = true;
}


// ============================================================================
// Set a single movement vector
// ============================================================================

void Cell::set_vector(Point position)
{
   march        = false;
   int side (which_side(position));
   clear_vector(all_vectors);

   if (side == -1) {
      return;
   }

   vector[side] = true;
   changed      = true;
}


// ============================================================================
// Clear one or all movement vectors
// ============================================================================

void Cell::clear_vector(int side)
{
   changed      = true;

   if (side != all_vectors) {
      vector[side] = false;
      return;
   }

   for (int i = 0; i < 6; i++) {
      vector[i] = false;
   }
}


// ============================================================================
// Return first vector set
// ============================================================================

int Cell::get_vector()
{
   for (int i = 0; i < 6; i++) {
      if (vector[i])return i;
   }

   return -1;
}


// ============================================================================
// Deal with a cell under attack
// ============================================================================

void Cell::battle(double elapsed)
{
   set<Cell *>::iterator p;
   double enemy_troops[6] = {0, 0, 0, 0, 0, 0};
   int    best_player(0);
   double best_troops(0);

   for (p = attackers.begin(); p != attackers.end(); p++) {
      Cell * enemy = *p;
      enemy_troops[enemy->player] += enemy->troops;
      if (enemy->troops > best_troops) {
         best_troops = enemy->troops;
         best_player = enemy->player;
      }
   }

   for (p = attackers.begin(); p != attackers.end(); p++) {

      if (troops <= 0)break;

      Cell * enemy = *p;
      if (enemy->troops <= 0)continue;

      int    eplayer         = enemy->player;
      double attacker_losses = troops * (troops / enemy_troops[eplayer]);
      double defender_losses = enemy->troops * (enemy_troops[eplayer]/troops);

      defender_losses *= 0.8;

      troops        -= (defender_losses * elapsed) / 10;
      enemy->troops -= (attacker_losses * elapsed) / 10;

      if (troops < 0)        troops        = 0;
      if (enemy->troops < 0) enemy->troops = 0;

      enemy->changed = true;
   }

   changed = true;
   attackers.clear();

   if (troops > 0) return;

   player = best_player;
   troops = 10;
   clear_vector(all_vectors);
}


// ============================================================================
// Return the centre coordinates of this cell
// ============================================================================

Point Cell::get_centre()
{
   Point centre;

   centre.x = position.x + (cell_size / 2);
   centre.y = position.y + (cell_size / 2);

   return centre;
}


// ============================================================================
// Merge cells preserving local values
// ============================================================================

void Cell::merge(const Cell & c) 
{
   elevation   = c.elevation;
   i           = c.i;
   j           = c.j;
   march       = c.march;
   march_timer = c.march_timer;
   player      = c.player;
   position    = c.position;
   troops      = c.troops;
   type        = c.type;
   strength    = c.strength;

   for (int k = 0; k < 6; k++) vector[k] = c.vector[k];
}



// ============================================================================
// Given a click return which side of a cell it selects
// ============================================================================

int Cell::which_side(Point click)
{
   Point centre (get_centre());

   int x (click.x - centre.x);
   int y (click.y - centre.y);

   const int centre_zone (cell_size / 6);

   if ((x > - centre_zone) && (x < centre_zone) &&
       (y > - centre_zone) && (y < centre_zone)) {
      return -1;
   }

   double radians (atan2(y, x));
   double angle   (radians * (180.0 / pi));

   if (angle < 0) angle += 360;

   return static_cast<int> (angle / 60.0);
}


// ============================================================================
// Cell output
//
// Streaming would be nice to send cells in the game but it's so cpu intensive.
// Hence, the cell streaming functions are only useful for tracing or writing
// to a file. Use the socket binary functions for the game updates.
// ============================================================================

ostream & operator<<(ostream & s, Cell & c)
{
   ostringstream buffer;

   buffer << c.i    << " " << c.j << " " << c.player << " " << c.troops << " "
          << c.type << " " << c.elevation << " " 
          << c.position.x << " " << c.position.y; 

   for (int i = 0; i < sizeof(c.vector); i++) {
      buffer << " " << c.vector[i];
   }

   return s << buffer.str();
}


// ============================================================================
// Cell input (how you should do it but it's so cpu intensive)
// ============================================================================

istream & operator>>(istream & s, Cell & c)
{
   s >> c.i >> c.j >> c.player >> c.troops >> c.type >> c.elevation
     >> c.position.x >> c.position.y; 

   if (s.bad() || s.fail()) {
      Exception e("Stream of class Cell failed");
      RAISE (e);
   }

   for (int i = 0; i < sizeof(c.vector); i++) {
      s >> c.vector[i];
   }

   return s;
}


// ============================================================================
// Send a cell in binary form (faster than streaming)
// ============================================================================

void send_cell(Socket & socket, Cell & cell) 
{
   CellBuffer buffer;

   buffer.sync      = 12345678;
   buffer.i         = cell.i;
   buffer.j         = cell.j;
   buffer.player    = cell.player;
   buffer.type      = cell.type;
   buffer.troops    = cell.troops;
   buffer.elevation = cell.elevation;
   buffer.position  = cell.position;
   buffer.strength  = cell.strength;

   memcpy(buffer.vector, cell.vector, sizeof(buffer.vector));
          
   socket.write_binary(&buffer, sizeof(buffer));
}


// ============================================================================
// Receive a cell (faster than streaming)
// ============================================================================

void read_cell(Socket & socket, Cell & cell) 
{
   CellBuffer buffer;

   socket.read_binary(&buffer, sizeof(buffer));

   if (buffer.sync != 12345678) {
      Exception e("Data transmission sync lost");
      RAISE(e);
   }

   cell.i         = buffer.i;
   cell.j         = buffer.j;
   cell.player    = buffer.player;
   cell.type      = buffer.type;
   cell.troops    = buffer.troops;
   cell.elevation = buffer.elevation;
   cell.position  = buffer.position;
   cell.strength  = buffer.strength;

   memcpy(cell.vector, buffer.vector, sizeof(cell.vector));
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -