PowerupType CPowerupManager::GetPowerup( const Core::CCoordinates& coordinates ) const
	{
		return GetPowerup( coordinates.x, coordinates.y );
	}
	void CPowerupManager::HandleStepForPlayer( CPlayer& activePlayer, std::vector<CPlayer>& players, std::set<CPlayer*>& crashedPlayers )
	{
		if( activePlayer.GetPosition() == activePlayer.GetPreviousPosition() ) {
			return;
		}
		if( GetPowerup( activePlayer.GetPosition().x, activePlayer.GetPosition().y ) != NONE ) {
			switch( powerups[activePlayer.GetPosition()] ) {
				case WALL:
					powerups.erase( activePlayer.GetPosition() );
					crashedPlayers.insert( &activePlayer );
					break;
				case SAND:
					powerups.erase( activePlayer.GetPosition() );
					activePlayer.SetInertia( { 0, 0 } );
					break;
				case OIL:
					powerups.erase( activePlayer.GetPosition() );
					activePlayer.SetInertia( { 0, 0 } );
					while( true ) {
						int direction = std::rand() % 9 + 1;
						if( direction != 5 ) {
							activePlayer.Move( Direction( direction ) );
							break;
						}
					}
					activePlayer.SetInertia( { 0, 0 } );
					break;
				case MINE:
					powerups[activePlayer.GetPosition()] = MINE_ACTIVE;
					break;
				case MINE_ACTIVE:
					powerups.erase( activePlayer.GetPosition() );
					crashedPlayers.insert( &activePlayer );
					break;
				case LAZER:
				{
					CCoordinates u = activePlayer.GetPosition() - activePlayer.GetPreviousPosition();
					double a = std::hypot( u.x, u.y ); // a > 0 всегда, т.к. соответствующая проверка выполнялась в начале функции
					for( auto& player : players ) {
						// геометрия. u - вектор движения, v - вектор от стреляющего до другого игрока
						// a и b - длины этих векторов соответственно, dot - скалярное произведение
						CCoordinates v = player.GetPosition() - activePlayer.GetPosition();
						double dot = u.x * v.x + u.y * v.y;
						double b = std::hypot( v.x, v.y );
						if( dot > 0 && b > 0 && std::sqrt( 1 - std::pow( dot / (a * b), 2 ) ) * b < 0.3 ) {
							crashedPlayers.insert( &player );
						}
					}
					powerups.erase( activePlayer.GetPosition() );
					shots.push_back( std::make_pair( 
						std::make_pair( activePlayer.GetPosition().x, activePlayer.GetPosition().y ),
						std::make_pair( float(u.x) / a, float(u.y) / a ) ) );
					break;
				}
				case SHIELD:
					powerups.erase( activePlayer.GetPosition() );
					activePlayer.ActivateShield();
					break;
				default: break;
			}
		}
		for( auto& player : players ) {
			handleWalls( player, crashedPlayers );
		}
	}
Esempio n. 3
0
//performs clipping each frame
void Clipping(void)
{
   LIST * cur1;
   LIST * cur2;
   LIST * next;

   for(cur1 = g_asteroid_list; cur1; cur1 = next)
   {
      next = cur1->next;

      if(g_ships
         && !g_player.wait_time
         && (((ASTEROID *)cur1->d)->region & g_player.region)
         && PolyInCircle(&g_player.clip_poly, &(((ASTEROID *)cur1->d)->clip_circle))) //if the player hits the asteroid
      {
         PlayerHit();
         AsteroidHit(cur1, 0);
         continue;
      }

      for(cur2 = g_alien_list; cur2; cur2 = cur2->next)
      {
         if((((ASTEROID *)cur1->d)->region & ((ALIEN *)cur2->d)->region)
            && (PolyInCircle(&(((ALIEN *)cur2->d)->clip_poly/*s[0]*/), &(((ASTEROID *)cur1->d)->clip_circle))
               /*|| PolyInCircle(&(((ALIEN *)cur2->d)->clip_polys[1]), &(((ASTEROID *)cur1->d)->clip_circle))
               || PolyInCircle(&(((ALIEN *)cur2->d)->clip_polys[2]), &(((ASTEROID *)cur1->d)->clip_circle))*/))
         {
            AlienHit(cur2, 0);
            AsteroidHit(cur1, 0);
            break;
         }
      }
      if(cur2) //if we broke early from the loop
         continue;

      for(cur2 = g_shot_list; cur2; cur2 = cur2->next)
      {
         if((((ASTEROID *)cur1->d)->region & ((SHOT *)cur2->d)->region)
            && PointInCircle(&(((SHOT *)cur2->d)->pos), &(((ASTEROID *)cur1->d)->clip_circle))) //if any shot hits the asteroid
         {
            AsteroidHit(cur1, ((SHOT *)cur2->d)->player_owned);
            RemoveNode(cur2, &g_shot_list);
            break;
         }
      }
      if(cur2) //if we broke early from the loop
         continue;
   }

   for(cur1 = g_shot_list; cur1; cur1 = next)
   {
      next = cur1->next;

      if(!((SHOT *)cur1->d)->player_owned
         && g_ships
         && !g_player.wait_time
         && (g_player.region & ((SHOT *)cur1->d)->region)
         && PointInPoly(&(((SHOT *)cur1->d)->pos), &g_player.clip_poly)) //if the alien shot is inside player
      {
         RemoveNode(cur1, &g_shot_list);
         PlayerHit();
         continue;
      }

      if(((SHOT *)cur1->d)->player_owned)
      {
         for(cur2 = g_alien_list; cur2; cur2 = cur2->next)
         {
            if((((SHOT *)cur1->d)->region & ((ALIEN *)cur2->d)->region)
               && (PointInPoly(&(((SHOT *)cur1->d)->pos), &(((ALIEN *)cur2->d)->clip_poly/*s[0]*/))
                  /*|| PointInPoly(&(((SHOT *)cur1->d)->pos), &(((ALIEN *)cur2->d)->clip_polys[1]))
                  || PointInPoly(&(((SHOT *)cur1->d)->pos), &(((ALIEN *)cur2->d)->clip_polys[2]))*/))
            {
               RemoveNode(cur1, &g_shot_list);
               AlienHit(cur2, 1);
               break;
            }
         }
         if(cur2)
            continue;
      }

      for(cur2 = g_powerup_list; cur2; cur2 = cur2->next)
      {
         if((((SHOT *)cur1->d)->region & ((POWERUP *)cur2->d)->region)
            && PointInCircle(&(((SHOT *)cur1->d)->pos), &(((POWERUP *)cur2->d)->clip_circle)))
         {
            PowerupHit(cur2, ((SHOT *)cur1->d)->player_owned);
            RemoveNode(cur1, &g_shot_list);
            break;
         }
      }
      if(cur2)
         continue;
   }

   if(g_ships
      && !g_player.wait_time)
   {
      for(cur1 = g_alien_list; cur1; cur1 = cur1->next)
      {
         if((g_player.region & ((ALIEN *)cur1->d)->region)
            && (PolyInPoly(&g_player.clip_poly, &(((ALIEN *)cur1->d)->clip_poly/*s[0]*/))
               /*|| PolyInPoly(&g_player.clip_poly, &(((ALIEN *)cur1->d)->clip_polys[1]))
               || PolyInPoly(&g_player.clip_poly, &(((ALIEN *)cur1->d)->clip_polys[2]))*/))
         {
            PlayerHit();
            AlienHit(cur1, 0);
            break;
         }
      }
   }

   if(g_ships)
   {
      for(cur1 = g_powerup_list; cur1; cur1 = next)
      {
         next = cur1->next;

         if((g_player.region & ((POWERUP *)cur1->d)->region)
            && PolyInCircle(&g_player.clip_poly, &(((POWERUP *)cur1->d)->clip_circle)))
         {
            GetPowerup(cur1);
            continue;
         }
      }
   }
}